home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d18 / opbonus.arc / ISRES.ARC / ISRES.PAS < prev    next >
Pascal/Delphi Source File  |  1991-03-20  |  6KB  |  192 lines

  1. {$S-,R-,V-,I-,B-,F-}
  2.  
  3. {*********************************************************}
  4. {*                    ISRES.PAS 1.00                     *}
  5. {*        Copyright (c) TurboPower Software 1990.        *}
  6. {*                  All rights reserved.                 *}
  7. {*********************************************************}
  8.  
  9. unit IsRes;
  10.   {-Routines that allow a program to determine if another copy of itself is
  11.     already resident in memory}
  12.  
  13. interface
  14.  
  15. type
  16.   ProgramName = string[8];
  17.  
  18. procedure Install(Name : ProgramName; UserHook : Pointer);
  19.   {-Install this program}
  20.  
  21. procedure Uninstall;
  22.   {-Uninstall this program}
  23.  
  24. function IsLoaded(Name : String; var UserHook : Pointer) : Boolean;
  25.   {-Returns True if Name is loaded}
  26.  
  27. procedure Init16;
  28.   {-Install interrupt handler. Called automatically when program begins}
  29.  
  30. procedure Restore16;
  31.   {-Restore INT $16 vector. Called automatically when program ends}
  32.  
  33.   {==========================================================================}
  34.  
  35. implementation
  36.  
  37. type
  38.   IfcPtr = ^IfcRecord;
  39.   IfcRecord =               {*** do not change!! ***}
  40.     record
  41.       NamePtr : ^String;
  42.       Version : Word;
  43.       UserPtr : Pointer;
  44.       PrevIfc : IfcPtr;
  45.       NextIfc : IfcPtr;
  46.       PrgName : ProgramName;
  47.     end;
  48. const
  49.   IfcSignature1   = $0F0F0;    {*** do not change!! ***}
  50.   IfcSignature2   = $0E0E0;    {*** do not change!! ***}
  51. var
  52.   SaveExitProc    : Pointer;
  53.   ThisIfcPtr      : IfcPtr;
  54.   IfcInstalledPtr : ^Boolean;
  55.  
  56.   {$L ISRES.OBJ}
  57.  
  58.   procedure Init16; external;
  59.   procedure Restore16; external;
  60.   procedure ThisIfc; external;
  61.  
  62.   function GetLastModulePtr : IfcPtr;
  63.     {-Return a pointer to the last module loaded before us}
  64.   var
  65.     FoundIfc : Boolean;
  66.     P : IfcPtr;
  67.     IACAptr : Pointer absolute $40:$F0;
  68.     SaveIACA : Pointer;
  69.   begin
  70.     {assume failure}
  71.     P := nil;
  72.     SaveIACA := IACAptr;
  73.     IACAptr := nil;
  74.  
  75.     inline(
  76.       $B8/>IfcSignature1/    {mov ax,>IfcSignature1  ;standard interface function code}
  77.       $31/$FF/               {xor di,di              ;es:di = nil}
  78.       $8E/$C7/               {mov es,di}
  79.       $CD/$16/               {int $16                ;call INT 16}
  80.       $F7/$D0/               {not ax                 ;flip bits}
  81.       $3D/>IfcSignature1/    {cmp ax,>IfcSignature1  ;AX = IfcSignature1 only if INT 16 flipped bits}
  82.       $75/$1E/               {jne Done               ;Ifc handler not found?}
  83.       $8C/$C0/               {mov ax,es              ;use second method if es:di = nil}
  84.       $09/$F8/               {or ax,di}
  85.       $74/$08/               {jz NotFound}
  86.       $89/$7E/<P/            {mov [bp+<P],di         ;offset of list pointer in P}
  87.       $8C/$46/<P+2/          {mov [bp+<P+2],es       ;segment of list pointer in P}
  88.       $EB/$0C/               {jmp short Found}
  89.                              {NotFound:              ;try second method - SuperKey can defeat the first}
  90.       $B8/>IfcSignature2/    {mov ax,>IfcSignature2  ;secondary function code}
  91.       $CD/$16/               {int $16                ;call INT 16}
  92.       $F7/$D0/               {not ax                 ;AX = not AX}
  93.       $3D/>IfcSignature2/    {cmp ax,>IfcSignature2  ;AX = IfcSignature2?}
  94.       $75/$04/               {jne Done               ;Ifc handler not found?}
  95.                              {Found:}
  96.       $C6/$46/<FoundIfc/$01);{mov [bp+<FoundIfc],1   ;set Found flag}
  97.                              {Done:}
  98.  
  99.       if not FoundIfc then
  100.         GetLastModulePtr := nil
  101.       else if P <> nil then
  102.         GetLastModulePtr := P
  103.       else
  104.         GetLastModulePtr := IACAptr;
  105.  
  106.       {restore intra-applications comm. area}
  107.       IACAptr := SaveIACA;
  108.   end;
  109.  
  110.   procedure Install(Name : ProgramName; UserHook : Pointer);
  111.     {-Install this program}
  112.   var
  113.     P : IfcPtr;
  114.   begin
  115.     if (Name <> '') and not IfcInstalledPtr^ then
  116.       with ThisIfcPtr^ do begin
  117.         {see if anyone else is home}
  118.         P := GetLastModulePtr;
  119.         if P <> nil then begin
  120.           P^.NextIfc := ThisIfcPtr;
  121.           PrevIfc := P;
  122.         end
  123.         else
  124.           PrevIfc := nil;
  125.  
  126.         {initialize the other fields in the record}
  127.         PrgName := Name;
  128.         NextIfc := nil;
  129.         UserPtr := UserHook;
  130.  
  131.         IfcInstalledPtr^ := True;
  132.       end;
  133.   end;
  134.  
  135.   procedure Uninstall;
  136.     {-Uninstall this program}
  137.   begin
  138.     if IfcInstalledPtr^ then
  139.       with ThisIfcPtr^ do begin
  140.         {fix the linked list of modules}
  141.         if PrevIfc <> nil then
  142.           PrevIfc^.NextIfc := NextIfc;
  143.         if NextIfc <> nil then
  144.           NextIfc^.PrevIfc := PrevIfc;
  145.         IfcInstalledPtr^ := False;
  146.       end;
  147.   end;
  148.  
  149.   function IsLoaded(Name : String; var UserHook : Pointer) : Boolean;
  150.     {-Returns True if Name is loaded}
  151.   var
  152.     P : IfcPtr;
  153.   begin
  154.     {search backward through the list}
  155.     P := GetLastModulePtr;
  156.     while (P <> nil) do begin
  157.       if P^.NamePtr^ = Name then begin
  158.         UserHook := P^.UserPtr;
  159.         IsLoaded := True;
  160.         Exit;
  161.       end;
  162.       P := P^.PrevIfc;
  163.     end;
  164.  
  165.     {search failed}
  166.     IsLoaded := False;
  167.   end;
  168.  
  169.   {$F+}
  170.   procedure OurExitProc;
  171.     {-Error/exit handler}
  172.   begin
  173.     {restore previous exit handler}
  174.     ExitProc := SaveExitProc;
  175.  
  176.     {remove the program from the list}
  177.     Uninstall;
  178.  
  179.     {restore INT $16}
  180.     Restore16;
  181.   end;
  182.   {$F-}
  183.  
  184. begin
  185.   {take over INT $16 and initialize pointers}
  186.   Init16;
  187.  
  188.   {set up exit handler}
  189.   SaveExitProc := ExitProc;
  190.   ExitProc := @OurExitProc;
  191. end.
  192.